#pragma warning (disable : 4786) 

#define __hiddedebug__

// Este Archivo se ocupa de leer el archivo de entrada y generar los elementos que se guardan en el contenedor de XML



#ifndef __CXMLPARSER_INCLUDED__
#define __CXMLPARSER_INCLUDED__
#include "c_xmlparser.h"
#endif

#include "..\..\common\logger.h"


c_xmlparser::~c_xmlparser(){
	int p_list_total;
    
    p_list_total = xml_lines.size()-1;

    for (int i=p_list_total;i>=0;i--){        
        delete xml_lines[i];
        xml_lines.pop_back();
     
        }  

}

int c_xmlparser::OpenFile(char* file_to_read){
    infile.open(file_to_read);
    if (!infile) return(false);
    else return(true);
}



int c_xmlparser::ReadFile(char* file_to_read)
{
std::string line;
  
// std::cout<<"LEE PARSER"<<std::endl;   
if   (file_to_read!=NULL&&OpenFile(file_to_read))
{
       
       while (infile.peek() != EOF) {
		     std::getline(infile, line); // next l
             lines.push_back(line); //append
			 //std::cout<<line<<std::endl; 
             }

             infile.close();
}
else
{    //std::cout<<"ELSE PARSER"<<std::endl;  
     return(0);
}
return(lines.size());
}




int c_xmlparser::Parse_File(void){

	int p_list_total;
//	int resultado;

    p_list_total = lines.size();

		for (int i=0;i<p_list_total;i++){   
			
			xml_info.append(lines[i]);

			//Parse_Line(i);
			
		}


		if (i > 0) {
			i=Parse_Xml_Info();	
		
		
			if (i>0) {
				Parse_Xml();
			int on = XML_List.Open_Nodes();
			if (on >0)
				{
			
				std::string out_msg;
				out_msg.assign("XML-Parser(dice)-->Hay nodos que quedaron Abietos De todas formas, Sera Dibujado.!!!");
				logger::getInstancia()->log(out_msg);
				
				#ifndef __hiddedebug__
				std::cout<<out_msg<<std::endl;
				#endif


				}
			}
			
		
		





		/******************************VALIDAR DTD**********************************/
		//dtd_node = new c_xml_dtd_node("end_node","escenario",2,1,1);
		//dtd_lines.push_back(dtd_node); // Agrega comando a la lista de comandos
		
		/********************CARGO DTD DE ARCHIVO*************/
			int linea = 1;
			char param1[200], param2[200]; //para validar nodos
			int param3, param4, param5; //para validadr nodos


			int Leer_Mas = LeerDeArchivo("validos.txt", param1, param2, &param3, &param4, &param5, linea);

			while(Leer_Mas!=-1)
			{
				dtd_node = new c_xml_dtd_node(param1,param2,param3,param4,param5);
				dtd_lines.push_back(dtd_node); // Agrega comando a la lista de comandos
				linea++;
				Leer_Mas = LeerDeArchivo("validos.txt", param1, param2, &param3, &param4, &param5, linea);
			}
		/********************CARGO DTD DE ARCHIVO*************/

		
		
		char * name;
		name = new char[200];


		char * P_value;
		P_value = new char[200];




		int total_nodes;
		int cant_properties;


		int level;
		level = 0;
		
		int level_ant;
		level_ant = -1;

		int total_obligatorios_nodo;
		int total_obligatorios_propiedad;

		int thiscounter_obligatorios_nodo;
		int thiscounter_obligatorios_propiedad;

		int es_obligatorio;

		total_obligatorios_nodo = 0;
		total_obligatorios_propiedad = 0;
		thiscounter_obligatorios_nodo = 0;
		thiscounter_obligatorios_propiedad = 0;
		es_obligatorio = 0;

		std::vector<std::string> O_Nodes_List; 
		
		std::string node_tmp_name;
		
		char * node_tmp_name_2;
		node_tmp_name_2 = new char[200];


		total_nodes = XML_List.Get_Max_NodeId();

		int node_pointer;
		int node_type;
		
		//strcpy(node_ant_name,"end_node");
		
		
		
		std::cout<< "******************************************"<< std::endl;
		std::cout<< total_nodes << " Nodos Procesados" << std::endl;
		std::cout<< "Ver archivo-log para detalles" << std::endl;


	for (int i=0;i<total_nodes;i++){  // Se recorre la lista de nodos completa 

			XML_List[i]->GetName(name);
			level = XML_List[i]->Get_Level();
			cant_properties = XML_List[i]->GetPropertyCount();
			node_type = 3; // Tipo nodo 
		//	std::cout << "------------NUEVO NODO-------------" << std::endl;
		//	std::cout << name << " level:" << level << std::endl;
			
			
			
			//Agregar nombre nodo a una lista al subirse un nivel agregar nuevo nodo a lista y apuntar al anteultimo, al bajar un nivel borrar el ultimo y apuntar al anterior

			
			if (level==level_ant+1) { //Sube un nivel agrega nodo a la lista apunta al anterior
			
				if (level == 0){
					strcpy(node_tmp_name_2,"end_node");
					node_tmp_name.assign("end_node");
					O_Nodes_List.push_back(node_tmp_name);
					node_pointer = O_Nodes_List.size()-1;
				}
			
				else 
				{//std::cout<<"Se agrega a la lista: "<<node_tmp_name.c_str()<<std::endl;
					XML_List[i-1]->GetName(node_tmp_name_2);
				}
				node_tmp_name.assign(node_tmp_name_2);
				O_Nodes_List.push_back(node_tmp_name);
				node_pointer = O_Nodes_List.size()-1;
				level_ant = level;

				thiscounter_obligatorios_nodo = 0;

			}


			if (level==level_ant-1) { //Baja un nivel en la lista lo borra y apunta al ultimo
				
		
				if (thiscounter_obligatorios_nodo !=total_obligatorios_nodo) {
					
					std::string out_msg;
					out_msg.assign("XML-Parser(dice)-->:Faltaron nodos obligatorios adentro de:");
					out_msg.append(O_Nodes_List[node_pointer].c_str());
					logger::getInstancia()->log(out_msg);
				
				#ifndef __hiddedebug__
				std::cout<<out_msg<<std::endl;
				#endif
					

					total_obligatorios_nodo = 0;

				}
				
				//std::cout<<"Se saca el ultimo de la lista: "<<std::endl;
				//O_Nodes_List.pop_back();
				O_Nodes_List.erase(O_Nodes_List.begin()+O_Nodes_List.size()-1);
				node_pointer = O_Nodes_List.size()-1;
				level_ant = level;			

				thiscounter_obligatorios_nodo = 0;


			}

			
//**********************************************//

			//std::cout<<"Nodo Ext:"<<O_Nodes_List[node_pointer].c_str()<<std::endl;
			//std::cout<<"Nodo:"<<name<<std::endl;
			//std::cout<<node_type<<std::endl;
			
			es_obligatorio = pertenece_dtd(O_Nodes_List[node_pointer].c_str(), name, total_obligatorios_nodo, 3); //Nodo tipo 3

			if (es_obligatorio<0){
			
				std::string out_msg;
				out_msg.assign("XML-Parser(dice)-->El nodo:");
				out_msg.append(name);
				out_msg.append(" es invalido dentro de:");
				out_msg.append(O_Nodes_List[node_pointer].c_str());
				out_msg.append(" sera omitido");
				logger::getInstancia()->log(out_msg);
				
				#ifndef __hiddedebug__
				std::cout<<out_msg<<std::endl;
				#endif
					
			}
			if (es_obligatorio > 0) {thiscounter_obligatorios_nodo++;}

			
//**********************************************//
			
			


			

				for(int j=0;j<=cant_properties;j++){

					XML_List[i]->GetName(node_tmp_name_2);
					XML_List[i]->GetPropertyByID(j,name,P_value);

					//std::cout << "pertenece a:"<< node_tmp_name_2 << "  " << name << " value:" << P_value << std::endl;

					// Check properties
					es_obligatorio = pertenece_dtd(node_tmp_name_2, name, total_obligatorios_propiedad, 2); //Nodo tipo 2
					if (es_obligatorio<0){

						node_tmp_name.assign(name);
						//std::cout<<"busca valor:"<<node_tmp_name.find("int_valor_")<<std::endl;

						if (node_tmp_name.find("int_valor_") == 0)
						{

							//std::cout<<"busca valor"<<std::endl;
							strcpy(name,P_value); // Si es propiedad lo copia para mostrar en el error
						}
			
						
						std::string out_msg;
						out_msg.assign("XML-Parser(dice)-->El nodo:");
						out_msg.append(node_tmp_name_2);
						out_msg.append(" no admite la propiedad:");
						out_msg.append( name);
						out_msg.append(" sera omitido");
						logger::getInstancia()->log(out_msg);
						
						#ifndef __hiddedebug__
						std::cout<<out_msg<<std::endl;
						#endif
				
							
					}		
					if (es_obligatorio > 0) {thiscounter_obligatorios_propiedad++;}
					// Check properties

				} 

				// Check properties

				if (total_obligatorios_propiedad != thiscounter_obligatorios_propiedad){

					std::string out_msg;
					out_msg.assign("XML-Parser(dice)-->Faltan atributos obligatorios dentro de:");
					out_msg.append(node_tmp_name_2);

					#ifndef __hiddedebug__
						std::cout<<out_msg<<std::endl;
					#endif
				}

				total_obligatorios_propiedad = 0;
				thiscounter_obligatorios_propiedad = 0;
				// Check properties

		 }




delete[] name;	
delete[] P_value;	
delete[] node_tmp_name_2;
		
		
		
		
		/******************************VALIDAR DTD**********************************/
		
		
		
		
		
		
		
		
		}


	

		//std::cout<<xml_info;
     
	//	if (p_list_total!=0) {
	//		resultado = Parse_Xml();			
	//		return(resultado);
	//	}
	//	else {return(0);}
		return(0);

}



int c_xmlparser::Parse_Xml_Info(void){

int Line_Pos;
Line_Pos = 0;

int in_char34;
in_char34 = 0;

int in_comment;
in_comment = 0;


int in_tag;
in_tag = 0;

int command_ID;
int Lista_Comando;
Lista_Comando = 0;
char * Param1;
char * Param2;

Param1 = new char[200];
Param2 = new char[200];

int Pos_P1;
int Pos_P2;

Pos_P1=0;
Pos_P2=0;




		//std::cout<<"Procesa Linea:"<<Line_Number<<std::endl; 
		//std::cout<<"Procesa Linea:"<<lines[Line_Number]<<std::endl; 	
     


/*add_expected(65,90);

std::cout<<"IsExpected:A"<<is_expected('A')<<std::endl;

std::cout<<"IsExpected:a"<<is_expected('a')<<std::endl;
del_expected(65,66);

std::cout<<"IsExpected:A"<<is_expected('A')<<std::endl;
std::cout<<"IsExpected:B"<<is_expected('B')<<std::endl;
empty_expected();
std::cout<<"IsExpected:C"<<is_expected('C')<<std::endl;
std::cout<<"IsExpected:Z"<<is_expected('Z')<<std::endl;
*/


empty_expected();
add_expected('<'); // El unico permitido para comienzo de archivo


for(Line_Pos=0;(xml_info[Line_Pos] != '\n'&&xml_info[Line_Pos] != '\0');Line_Pos++)
{


switch(is_expected(xml_info[Line_Pos])) 

{ 

case 1:
	{
	
		//std::cout << "caracter:" << xml_info[Line_Pos] << "Esperado" << std::endl;
		
	if (in_tag==1){
		if (xml_info[Line_Pos]==34){
			if (in_char34==0) {in_char34=1;
			command_ID = 4; // Adentro de un valor atributo
			}
			else {in_char34=0;
			command_ID = 5; // Fin de un valor atributo
			
			}
		}

		if (xml_info[Line_Pos]==' '){
			if (in_char34!=0) {in_char34=0;
			command_ID = 5; // Adentro de un valor atributo
			}
		}

		


	}

		if (xml_info[Line_Pos]=='<'&&xml_info[Line_Pos+1]=='!'&&xml_info[Line_Pos+2]=='-'&&xml_info[Line_Pos+2]=='-'&&xml_info[Line_Pos+3]=='-'&&in_char34==0){ // es un comentario voy a tratar salir de el
			Line_Pos = Line_Pos + 4; // Entro a comentario
			in_comment = 1;
			for(Line_Pos=Line_Pos;(xml_info[Line_Pos] != '\n'&&xml_info[Line_Pos] != '\0'&&in_comment==1);Line_Pos++){

				if (xml_info[Line_Pos]=='-'&&xml_info[Line_Pos+1]=='-'&&xml_info[Line_Pos+2]=='>'){					
						in_comment = 0;
						Line_Pos = Line_Pos + 2; // Sale de cometario
					}

			}
				
			
		}




				if (xml_info[Line_Pos]=='<'&&xml_info[Line_Pos+1]=='?'&&in_char34==0){ // es un comentario voy a tratar salir de el
			Line_Pos = Line_Pos + 2; // Entro a comentario
			in_comment = 1;
			for(Line_Pos=Line_Pos;(xml_info[Line_Pos] != '\n'&&xml_info[Line_Pos] != '\0'&&in_comment==1);Line_Pos++){

				if (xml_info[Line_Pos]=='?'&&xml_info[Line_Pos+1]=='>'){					
						in_comment = 0;
						Line_Pos = Line_Pos + 1; // Sale de cometario
					}

			}
				
			
		}



		if(xml_info[Line_Pos]=='='&&in_char34==0) {command_ID=2;} // Otro lado del igual
		
		if (xml_info[Line_Pos]=='>'&&in_char34==0){


			
	/*	char a = xml_info[Line_Pos];
		char b = xml_info[Line_Pos+1];
		char c = xml_info[Line_Pos+2];
		char d = xml_info[Line_Pos+3];
		char e = xml_info[Line_Pos+4];
	*/
			if (in_tag==1) {
				in_tag=0;
				command_ID = 3; // cierra		
				}
				else
				{
				command_ID = -1;
				}

			//else {error?}
		}

		
		if (xml_info[Line_Pos]=='<'&&in_char34==0){
			if (in_tag==0) {
				in_tag=1;
				command_ID = 1; // abre tag			
			}
			//else {error?}
		}



		/***********************Procesa**************************/

		

		if (command_ID == 1||command_ID == -1) { // Abrio TAG
				if (xml_info[Line_Pos]!=' '&&xml_info[Line_Pos]!='='&&xml_info[Line_Pos]!='<'){						

					Param1[Pos_P1] = xml_info[Line_Pos];
					Pos_P1++;
				}
		
			else{
						
						
				if (Pos_P1 == 0&&command_ID==1) {
					Param1[0] = '<'; // Agrega tag de abrir
					Pos_P1++;
				}

					if (Pos_P1>0&&!(Pos_P1==1&&Param1[0] == '<')){ // Termino palabra						
						//std::cout << "Termina Palabra" <<std::endl;
						Param1[Pos_P1] = '\0';
						Param2[0] = '\0';
						
						//if (in_tag==0){
						//Command_Xml = new c_xml_parse_command(command_ID,Param1,Param2);
						//std::cout << "Palabra Capturada: "<< Param1 <<std::endl;
						if (command_ID == 1&&in_tag==1&&Param1[0]=='<') {Lista_Comando = 3;}// Capturo Palabra
						if (command_ID == 1&&in_tag==1&&Param1[0]!='<') {Lista_Comando = 1;}// Capturo Palabra
						if (command_ID == -1) {Lista_Comando = 1;} // Capturo Palabra
						//xml_lines.push_back(Command_Xml); // Agrega comando a la lista de comandos
						//}


						//Pos_P1 = 0;
						//Pos_P2 = 0;
						command_ID = -1; //Espera Proxima Instruccion
						
					}

					
				}
		}


				if (command_ID == 3) { // cierra TAG
				Param1[Pos_P1] = '\0';
				//std::cout << "Ultima Palabra antes de cerrar el tag: " << Param1 <<std::endl;
				Lista_Comando = 3; // Cerro TAG 
				//Pos_P1=0;
				command_ID = -1;
				}


			if (command_ID == 2) { 
				if (Pos_P1!=0) {Param1[Pos_P1]='\0';}
			//	std::cout << "Primer Lado de la Igualdad: " << Param1 <<std::endl;
				Pos_P1=0;
				command_ID = -1;

			}



			//std::cout << Param1 <<std::endl;




			if (command_ID == 4||command_ID == 5) { 
				if (command_ID == 4){
					Param2[Pos_P2] = xml_info[Line_Pos];
					Pos_P2++;
				}
				else
				{ 
					Param2[Pos_P2] = '\0';
					//std::cout << "Segundo Lado de la Igualdad: " << Param2 <<std::endl;				
					Lista_Comando = 5; // Igualdad
					command_ID = -1;
				}
					

			}



			if (Lista_Comando==1||Lista_Comando==3||Lista_Comando==5 ){
			
				if (Lista_Comando == 1 || Lista_Comando == 3) {Param2[0]='\0';} // No tienen segundo parametro

				/*	std::cout << "Lista_Comando: " << Lista_Comando <<std::endl;	
					std::cout << "Param1: " << Param1 <<std::endl;	
					std::cout << "Param2: " << Param2 <<std::endl;	
				*/
						
					
						int list_total = xml_lines.size();
						int No_Agregar;
						No_Agregar=0;


						//std::cout<<"Lineas: " << list_total << std::endl;

						
						if (list_total > 0 && Lista_Comando==5) { // Si es igualdad y agregue con comando 1 antes lo elimino y lo dejo solo como igualdad
							
							int Last_Id;
							char * Last_Param1;
							Last_Param1 = new char[200];
							
							xml_lines[list_total-1]->GetValues(Last_Id,Last_Param1);

							//std::cout<<"Last_ID: " << Last_Id << std::endl;


							if (Last_Id==3&&strcmp(Param1,Last_Param1)==0){
								No_Agregar=1;
								std::cout << "No agregar Actual"<<std::endl;
							}
							
							if ((Last_Id==1)&&strcmp(Param1,Last_Param1)==0){
								//std::cout << "Lo debo eliminar" <<std::endl;

								delete xml_lines[list_total-1];
								xml_lines.erase(xml_lines.begin()+list_total-1);

							}

						
							delete[] Last_Param1;
						}




					if (No_Agregar==0){
						Command_Xml = new c_xml_parse_command(Lista_Comando,Param1,Param2);
						xml_lines.push_back(Command_Xml); // Agrega comando a la lista de comandos
						}



						//std::cout << "Palabra Capturada: "<< Param1 <<std::endl;
					//	if (command_ID == 1) {Lista_Comando = 3;} // Capturo Palabra
					//	if (command_ID == -1) {Lista_Comando = 1;} // Capturo Palabra
						



					Lista_Comando = 0;
					Pos_P2 = 0;
					Pos_P1=0;
					Param2[0] = '\0';
			}

		/***********************Procesa**************************/

		load_expected(xml_info[Line_Pos],in_char34);



		break;
	}

case 0: 	
	{
	
		//std::cout << "caracter:" << xml_info[Line_Pos] << " No Esperado" << std::endl;

		break;
	}


return(xml_lines.size());

}; 





//	std::cout<<xml_info[Line_Pos];

}


//Control de errores

if (in_char34!=0){
	std::cout<<"chr34:"<<in_char34<<std::endl;
}

if (in_comment!=0){
	std::cout<<"in_comment:"<<in_comment<<std::endl;
}

if (in_tag!=0){
	std::cout<<"in_tag:"<<in_tag<<std::endl;
}
//Control de errores

//std::cout<<xml_info[Line_Pos];
//std::cout<<xml_info[Line_Pos];




delete []Param1;
delete []Param2;

return(1);

}





char c_xmlparser::load_expected(char after_char, int stat){



	if (after_char=='<'){ 
		empty_expected();
		add_expected(65,90); // A-Z
		add_expected(97,122); // a-z
		add_expected('/'); // a-z
	}

	if (after_char=='>'){ 
		empty_expected();
		add_expected('<');
		add_expected(' '); 
		add_expected(34);
		add_expected(' ');
		//add_expected(65,90); // A-Z
		//add_expected(97,122); // a-z
		//add_expected(48,57); // 0-9
		add_expected('<');
		add_expected('>');
		add_expected('/');
		add_expected('*');
		add_expected('.');
		add_expected(',');


	}


		if (after_char=='='){ 
		empty_expected();
		add_expected(' ');
		add_expected('"'); 
	}




	if ((after_char>64&&after_char<91)||(after_char>96&&after_char<123)){ 
		//std::cout<<"Es Caracter"<<std::endl;
		add_expected(48,57); // 0-9
		add_expected(' '); 
		add_expected('/'); 
		add_expected('='); 
		add_expected('>'); 
	}


		if (after_char=='/'){ 
		empty_expected();
		add_expected('>');
		add_expected(65,90); // A-Z
		add_expected(97,122); // a-z
	}



		if (stat==1) { 
			add_expected(34);
			add_expected(' ');
			add_expected(65,90); // A-Z
			add_expected(97,122); // a-z
			add_expected(48,57); // 0-9
			add_expected('<');
			add_expected('>');
			add_expected('/');
			add_expected('\\');
			add_expected(':');
			add_expected('*');
			add_expected('.');
			add_expected(',');
			add_expected('-');
			add_expected('_');

		}// Adentro de ""


return(0);
}






int c_xmlparser::add_expected(int from_char, int to_char){
int agregados;
agregados = 0;


	for(int i=from_char;i<=to_char;i++){
		
		if (is_expected(i) == 0) {
				Expected_Char_List.push_back(i); //append
				agregados++;
		}
	}

	return(agregados); // Caracteres agregados

}


int c_xmlparser::add_expected(char expected_char){

	if (is_expected(expected_char)==0) { // si no esta
			Expected_Char_List.push_back(expected_char); //append
			return(1); // Caracteres agregados
	}

	return(0);
}



int c_xmlparser::is_expected(char expected_char){

	int p_list_total;

    p_list_total = Expected_Char_List.size();

		for (int i=0;i<p_list_total;i++){   
        
			if (Expected_Char_List[i]==expected_char) {return(1);}
			
		}

	return(0);

}




int c_xmlparser::del_expected(char expected_char){

	int p_list_total;
	p_list_total = Expected_Char_List.size();

	for (int i=0;i<p_list_total;i++){   



		if (is_expected(expected_char)==1) {
			Expected_Char_List.erase(Expected_Char_List.begin()+i);
			//Expected_Char_List.remove(exepcted_char);
			return(1);
		}

		return(0);

	}

	return 0;

}


int c_xmlparser::del_expected(int from_char, int to_char){
int deleted;
deleted = 0;


	for(int i=from_char;i<=to_char;i++){
		
		if (is_expected(i) == 1) {
				del_expected(i); //delete
				deleted++;
		}
	}

	return(deleted); // Caracteres borrados

}




int c_xmlparser::empty_expected(){

	Expected_Char_List.clear();
	return(1);


}



int c_xmlparser::Parse_Xml(void){



int static n_id=0;
int ok_add;

int k;

int Inst_Id;
char * Param1;
char * Param2;

Param1 = new char[200];
Param2 = new char[200];
					
int p_list_total;

 
   p_list_total = xml_lines.size();	


   for (int i=0;i<p_list_total;i++){   

	   xml_lines[i]->GetValues(Inst_Id,Param1,Param2);

	   //std::cout<<"ID: " << Inst_Id << std::endl;

	switch(Inst_Id) 

	{ 

	case 1:{ 
				if (n_id!=-1) {
				std::cout<<"Valor para adentro de un tag ""int_valor_"": " << Param1 << std::endl;
				ok_add = XML_List[n_id]->add_propertie("int_valor_",Param1); }
				break;
			
		   }
	
	
	
	case 3:{ 
				//std::cout<<"ID: " << Inst_Id << std::endl;
				
				if (Param1[1] != '/'&&Param1[0] != '\0'&&Param1[0]!='/'){
					if (Param1[0]=='<'&&Param1[1]!='/') {

						for (k=1;Param1[k]!='\0';k++){ Param2[k-1] = Param1[k];} // saca / del principio
						Param2[k-1] = '\0';

							/**************************************/
						//	std::cout<<"Abre un nuevo tag con el nombre:" << Param2 << std::endl;
							n_id = XML_List.Insert_Node(Param2);
							/**************************************/

						Param2[0] = '\0';
					}
					else
					{
						std::cout<<"Se esperaba un valor para la propiedad"<<std::endl;
					}
							
				}

	
				if (Param1[0] == '\0'){
					//	std::cout<<"No hace nada se termino un tag con atributos:" << std::endl;
	
				}
		   


				if ((Param1[0] == '<'&&Param1[1]=='/')){
					for (k=2;Param1[k]!='\0';k++){ Param2[k-2] = Param1[k];} // saca / del principio
					Param2[k-2] = '\0';
						
					if ((k-1)>0){
						if (n_id!=-1) {
					//	std::cout<<"Cierra tag con el nombre:" << Param2 << std::endl;
						ok_add = XML_List.Close_Node_CheckName(Param2);
						}
					}
					//else
				
					Param2[0] = '\0';
				}
				
				if (Param1[0]=='/')
					{
						if (n_id!=-1) {
					//	std::cout<<"Cierra el ultimo tag" << std::endl;
						XML_List.Close_Last_Node();
						}
					}
	

				break;

		   }
	
	
	case 5:{

				
				char * tmp_param;
				tmp_param = new char[200];


				if (Param2[0]==34) {
					for (k=1;Param2[k]!='\0';k++){ tmp_param[k-1] = Param2[k];} // saca / del principio
					tmp_param[k-1] = '\0';
					strcpy(Param2,tmp_param);
				}

				delete[] tmp_param;

				if (n_id!=-1) {
				#ifndef __hiddedebug__
				std::cout<<"Propiedad: "<< Param1 << " Valor: " << Param2 << std::endl;	
				#endif
				ok_add = XML_List[n_id]->add_propertie(Param1,Param2);}
					
				if (ok_add == 1) {
					tmp_param = new char[200];

					XML_List[n_id]->GetName(tmp_param);
					std::cout<<"No se pudo agregar la propiedad:"<< Param1  <<" con valor:"<<Param2<<" en " << tmp_param << " verificar que no este repetido" << std::endl;
				
					delete[] tmp_param;
				}
				
				break;

		   }
	
	}; 













	/*	xml_lines[i]->GetValues(Inst_Id,Param1,Param2);
		std::cout<<"ID: " << Inst_Id << std::endl;
		std::cout<<"Param1: " << Param1 << std::endl;
		if (Param2!=NULL) {std::cout<<"Param2: " << Param2 << std::endl;}
	*/
	}


							
							
delete[] Param1;
delete[] Param2;


return(0);

}


int c_xmlparser::pertenece_dtd(const char* IN_C_Node, char* IN_P_Name, int &tot_obligatorios, int IN_node_type){


char * C_Node;
C_Node = new char[200];


char * P_Name;
P_Name = new char[200];


int node_type;
int obligatorio;
int total_obligatorios;

int total_list;

    total_list = dtd_lines.size();

		for (int i=0;i<total_list;i++){   
        
			dtd_lines[i]->GetValues(C_Node, P_Name, node_type, obligatorio, total_obligatorios);
			if (strcmp(IN_C_Node,C_Node)==0&&strcmp(IN_P_Name,P_Name)==0){
				tot_obligatorios = total_obligatorios;
				return(obligatorio);}
			
		}


delete[] C_Node;
delete[] P_Name;
return(-1);
}


int c_xmlparser::LeerDeArchivo(const char* nameFile, char *param1, char *param2, int *param3, int *param4, int *param5, int Linea )
{
	FILE* fd;
	int lineaLeida=0;
	char buffer[81];
	memset(buffer, 0, 80);
	fd=fopen(nameFile, "r");
	if (fd == NULL)
	{
		return -1;
	}
	do{
		if(lineaLeida==Linea)
		{
			sscanf( buffer, "%s %s %d %d %d", param1, param2, param3, param4, param5 );
			fclose(fd);
			return 0;
		}
		lineaLeida++;
	}while(fgets(buffer, 81, fd)!= NULL);
	fclose(fd);
	return -1;
}